﻿using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace Cpuss.Strategies
{

    /// <summary>
    /// First-Come-First-Served strategy.
    /// </summary>
    /// <remarks>
    /// Processes are executed in the order in which they arrived. This version of FCFS does not use a secondary
    /// clause when more than one process arrives at the same time.
    /// </remarks>
    public sealed class FirstComeFirstServed : IStrategy
    {

        /// <summary>
        /// Executes the processes in <see cref="Runner.ProcessLoad"/> in FCFS order.
        /// </summary>
        /// <param name="runner">Runner to use as execution enviroment.</param>
        public void Execute(Runner runner)
        {
            Queue<Process> readyQueue = new Queue<Process>(runner.ProcessLoad.OrderBy(x => x.ArrivalTime));

            while (readyQueue.Count > 0)
            {
                Process process = readyQueue.Dequeue();
                runner.SkipIdleCpuTime(process);

                while (!Process.IsComplete(process))
                {
                    runner.UtilizeCpu(process);
                }

                runner.LogProcessMetrics(process);
            }
        }

        /// <summary>
        /// Returns a <see cref="string"/> that represents the current <see cref="object"/>.
        /// </summary>
        /// <returns>String representation of object.</returns>
        public override string ToString()
        {
            return string.Format(CultureInfo.InvariantCulture, "First Come First Served");
        }

    }

}